package org.kfish.framework.helper;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.kfish.framework.bean.FileParam;
import org.kfish.framework.bean.FormParam;
import org.kfish.framework.bean.Param;
import org.kfish.framework.log.Log;
import org.kfish.framework.log.Log.LogType;
import org.kfish.framework.util.CollectionUtil;
import org.kfish.framework.util.FileUtil;
import org.kfish.framework.util.MapUtil;
import org.kfish.framework.util.StreamUtil;
import org.kfish.framework.util.StringUtil;

public class UploadHelper {

	private static ServletFileUpload servletFileUpload;

	public static void init(ServletContext servletContext) {
		// 设置临时文件路径
		File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
		servletFileUpload = new ServletFileUpload(
				new DiskFileItemFactory(DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD, repository));

		int uploadLimit = ConfigHelper.getUploadLimit();
		// 设置上传文件大小
		if (uploadLimit != 0) {
			servletFileUpload.setFileSizeMax(uploadLimit * 1024 * 1024);
		}

	}

	/**
	 * 使用 apache commons 的库，判断类型是否为mutipart,如果是，多半带有文件
	 * 
	 * @param request
	 * @return
	 */
	public static boolean isMultipart(HttpServletRequest request) {
		return ServletFileUpload.isMultipartContent(request);
	}

	public static Param createParam(HttpServletRequest request) throws IOException {
		List<FormParam> formParamList = new ArrayList<>();
		List<FileParam> fileParamList = new ArrayList<>();

		try {
			
			Map<String, List<FileItem>> paramMap = servletFileUpload.parseParameterMap(request);
			
			if(MapUtil.isNotEmpty(paramMap)){
				for(Entry<String, List<FileItem>> paramEntry: paramMap.entrySet()){
					String fieldName = paramEntry.getKey();
					
					List<FileItem> fileItemList = paramEntry.getValue();
					
					if (CollectionUtil.isNotEmpty(fileItemList)) {
						for (FileItem fileItem : fileItemList) {
							// 如果是表单数据
							if (fileItem.isFormField()) {
								String fieldValue = fileItem.getString("UTF-8");
								formParamList.add(new FormParam(fieldName, fieldValue));
							} else {
								// 从文件路径中获取文件名(此库考虑了路径分隔符在不同系统下的不同表现'/','\')
								String fileName = FilenameUtils.getName(new String(fileItem.getName().getBytes(), "UTF-8"));
								if (StringUtil.isNotEmpty(fileName)) {
									long fileSize = fileItem.getSize();
									String contentType = fileItem.getContentType();
									InputStream inputStream = fileItem.getInputStream();

									fileParamList.add(new FileParam(fieldName, fileName, contentType, fileSize, inputStream));

								}
							}
						}

					}
				}
			}
			
	

		} catch (FileUploadException e) {
			Log.getLogger(LogType.DETAIL).error("create param failure", e);
			throw new RuntimeException(e);

		}
		return new Param(formParamList, fileParamList);
	}

	public static void uploadFile(String basePath, FileParam fileParam) {
		try {
			if (fileParam != null) {
				String filePath = basePath + fileParam.getFileName();
				FileUtil.createFile(filePath);
				InputStream in = fileParam.getInputStream();
				OutputStream out = new BufferedOutputStream(new FileOutputStream(filePath));
				StreamUtil.copyStream(in, out);
			}
		} catch (FileNotFoundException e) {
			Log.getLogger(LogType.DETAIL).error("upload file failure", e);
			throw new RuntimeException(e);
		}
	}

	public static void uploadFile(String basePath, List<FileParam> fileParamList) {
		if (CollectionUtil.isNotEmpty(fileParamList)) {
			for (FileParam fileParam : fileParamList) {
				uploadFile(basePath, fileParam);
			}
		}
	}

}
